package com.ruoyi.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dyun.tool.mybatis.domain.PageDomain;
import com.ruoyi.common.annotation.SysLog;
import com.ruoyi.common.enums.BusinessTypeEnum;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.support.DateRange;
import com.ruoyi.project.system.entity.SysDictData;
import com.ruoyi.project.system.entity.SysDictType;
import com.ruoyi.project.system.service.ISysDictDataService;
import com.ruoyi.project.system.service.ISysDictTypeService;
import lombok.AllArgsConstructor;
import net.dreamlu.mica.core.result.R;
import net.dreamlu.mica.core.utils.$;
import net.dreamlu.mica.core.validation.CreateGroup;
import net.dreamlu.mica.core.validation.UpdateGroup;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 字典类型 控制层
 *
 * @author dy
 */
@RestController
@RequestMapping("/system/dict/type")
@AllArgsConstructor
public class SysDictTypeController extends BaseController {

    private final ISysDictTypeService sysDictTypeService;

    private final ISysDictDataService sysDictDataService;

    /**
     * 分页
     */
    @PreAuthorize("@ss.hasPermi('system:dict:list')")
    @GetMapping("/list")
    public R<IPage<SysDictType>> list(SysDictType sysDictType, PageDomain pageDomain, DateRange dateRange) {
        IPage<SysDictType> pages = sysDictTypeService.page(startPage(pageDomain),
                new LambdaQueryWrapper<SysDictType>()
                        .like($.isNotBlank(sysDictType.getDictName()), SysDictType::getDictName, sysDictType.getDictName())
                        .like($.isNotBlank(sysDictType.getDictType()), SysDictType::getDictType, sysDictType.getDictType())
                        .eq($.isNotNull(sysDictType.getStatus()), SysDictType::getStatus, sysDictType.getStatus())
                        .between($.isAnyNotBlank(dateRange.getBeginTime(), dateRange.getEndTime()), SysDictType::getCreateTime, dateRange.getBeginTime(), dateRange.getEndTime())
        );
        return success(pages);
    }

    /**
     * 详情
     */
    @PreAuthorize("@ss.hasPermi('system:dict:query')")
    @GetMapping("/detail")
    public R<SysDictType> detail(Long id) {
        return success(sysDictTypeService.getById(id));
    }

    /**
     * 新增
     */
    @SysLog(title = "字典类型", businessType = BusinessTypeEnum.INSERT)
    @PreAuthorize("@ss.hasPermi('system:dict:add')")
    @PostMapping("/add")
    public R add(@Validated(value = {CreateGroup.class}) @RequestBody SysDictType sysDictType) {
        int sysDictNum = sysDictTypeService.count(new LambdaQueryWrapper<SysDictType>()
                .eq($.isNotBlank(sysDictType.getDictType()), SysDictType::getDictType, sysDictType.getDictType()));
        if (sysDictNum > 0) {
            return fail("新增字典[" + sysDictType.getDictName() + "]失败，字典类型已存在");
        }
        return status(sysDictTypeService.saveIgnore(sysDictType));
    }

    /**
     * 修改
     */
    @SysLog(title = "字典类型", businessType = BusinessTypeEnum.UPDATE)
    @PreAuthorize("@ss.hasPermi('system:dict:edit')")
    @PutMapping("/update")
    public R update(@Validated(value = {UpdateGroup.class}) @RequestBody SysDictType editDictType) {
        SysDictType checkDictType = sysDictTypeService.getOne(new LambdaQueryWrapper<SysDictType>()
                .eq($.isNotBlank(editDictType.getDictType()), SysDictType::getDictType, editDictType.getDictType()));
        if (checkDictType != null && !checkDictType.getId().equals(editDictType.getId())) {
            return fail("修改字典[" + editDictType.getDictName() + "]失败，字典类型已存在");
        }
        if (checkDictType == null) {
            SysDictType oldDictType = sysDictTypeService.getById(editDictType.getId());
            if (!oldDictType.getDictType().equals(editDictType.getDictType())) {
                // 修改sys_dict_data的dict_type
                sysDictDataService.update(new LambdaUpdateWrapper<SysDictData>()
                        .set(SysDictData::getDictType, editDictType.getDictType())
                        .eq(SysDictData::getDictType, oldDictType.getDictType()));
            }
        }
        return status(sysDictTypeService.updateById(editDictType));
    }

    /**
     * 删除
     */
    @SysLog(title = "字典类型", businessType = BusinessTypeEnum.DELETE)
    @PreAuthorize("@ss.hasPermi('system:dict:remove')")
    @DeleteMapping("/delete/{ids}")
    public R delete(@PathVariable Long[] ids) {
        List<SysDictType> sysDictTypes = new ArrayList<>();
        List<Long> idList = new ArrayList<>(Arrays.asList(ids));
        idList.forEach(v -> {
            SysDictType sysDictType = new SysDictType();
            sysDictType.setId(v);
            sysDictTypes.add(sysDictType);

            // 循环判断是否已经分配
            SysDictType byId = sysDictTypeService.getById(v);
            int count = sysDictDataService.count(new LambdaQueryWrapper<SysDictData>().eq($.isNotNull(byId), SysDictData::getDictType, byId.getDictType()));
            if (count > 0) {
                throw new CustomException(String.format("%1$s已分配,不能删除", byId.getDictName()));
            }
        });
        boolean result = sysDictTypeService.updateBatchById(sysDictTypes) && sysDictTypeService.removeByIds(idList);
        return status(result);
    }
}
